home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP07.ZIP / CHAP07 / DATATRAN / IDATAOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-05-25  |  10KB  |  402 lines

  1. /*
  2.  * IDATAOBJ.CPP
  3.  * Data Tranfer Object for Chapter 7
  4.  *
  5.  * Implementation of the IDataObject interface for CDataObject.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include "dataobj.h"
  18.  
  19.  
  20.  
  21. /*
  22.  * CImpIDataObject::CImpIDataObject
  23.  * CImpIDataObject::~CImpIDataObject
  24.  *
  25.  * Parameters (Constructor):
  26.  *  pObj            LPVOID of the object we're in.
  27.  *  punkOuter       LPUNKNOWN to which we delegate.
  28.  */
  29.  
  30. CImpIDataObject::CImpIDataObject(LPCDataObject pObj, LPUNKNOWN punkOuter)
  31.     {
  32.     m_cRef=0;
  33.     m_pObj=pObj;
  34.     m_punkOuter=punkOuter;
  35.     return;
  36.     }
  37.  
  38. CImpIDataObject::~CImpIDataObject(void)
  39.     {
  40.     return;
  41.     }
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIDataObject::QueryInterface
  47.  * CImpIDataObject::AddRef
  48.  * CImpIDataObject::Release
  49.  *
  50.  * Purpose:
  51.  *  IUnknown members for CImpIDataObject object.
  52.  */
  53.  
  54. STDMETHODIMP CImpIDataObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  55.     {
  56.     return m_punkOuter->QueryInterface(riid, ppv);
  57.     }
  58.  
  59.  
  60. STDMETHODIMP_(ULONG) CImpIDataObject::AddRef(void)
  61.     {
  62.     ++m_cRef;
  63.     return m_punkOuter->AddRef();
  64.     }
  65.  
  66. STDMETHODIMP_(ULONG) CImpIDataObject::Release(void)
  67.     {
  68.     --m_cRef;
  69.     return m_punkOuter->Release();
  70.     }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. /*
  77.  * CImpIDataObject::GetData
  78.  *
  79.  * Purpose:
  80.  *  Retrieves data described by a specific FormatEtc into a StgMedium
  81.  *  allocated by this function.  Used like GetClipboardData.
  82.  *
  83.  * Parameters:
  84.  *  pFE             LPFORMATETC describing the desired data.
  85.  *  pSTM            LPSTGMEDIUM in which to return the data.
  86.  *
  87.  * Return Value:
  88.  *  HRESULT         NOERROR on success, error code otherwise.
  89.  */
  90.  
  91. STDMETHODIMP CImpIDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  92.     {
  93.     UINT        i, cItems;
  94.     LPRENDERING pRen;
  95.     DWORD       cb;
  96.     HWND        hList;
  97.  
  98.     if (NULL==m_pObj->m_hList || NULL==pFE || NULL==pSTM)
  99.         return ResultFromScode(DATA_E_FORMATETC);
  100.  
  101.     hList=m_pObj->m_hList;
  102.     cItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L);
  103.  
  104.     for (i=0; i < cItems; i++)
  105.         {
  106.         cb=SendMessage(hList, LB_GETTEXT, i, (LPARAM)(LPVOID)&pRen);
  107.  
  108.         if (sizeof(LPRENDERING)==cb)
  109.             {
  110.             /*
  111.              * Check if the requested FORMATETC is the same as one
  112.              * that we already have.  If so, then copy that STGMEDIUM
  113.              * to pSTM and AddRef ourselves for pUnkForRelease.
  114.              */
  115.             if (pFE->cfFormat==pRen->fe.cfFormat
  116.                 && (pFE->tymed & pRen->fe.tymed)
  117.                 && pFE->dwAspect==pRen->fe.dwAspect)
  118.                 {
  119.                 *pSTM=pRen->stm;
  120.                 AddRef();
  121.                 return NOERROR;
  122.                 }
  123.             }
  124.         }
  125.  
  126.     return ResultFromScode(DATA_E_FORMATETC);
  127.     }
  128.  
  129.  
  130.  
  131. /*
  132.  * CImpIDataObject::GetDataHere
  133.  *
  134.  * Purpose:
  135.  *  Copies a piece of data in this data object to another STGMEDIUM.
  136.  *  This is only supported for TYMED_ISTORAGE.
  137.  *
  138.  * Parameters:
  139.  *  pFE             LPFORMATETC describing the desired data.
  140.  *  pSTM            LPSTGMEDIUM pointing to the medium into which we copy.
  141.  *
  142.  * Return Value:
  143.  *  HRESULT         NOERROR on success, error code otherwise.
  144.  */
  145.  
  146. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  147.     {
  148.     UINT        i, cItems;
  149.     LPRENDERING pRen;
  150.     DWORD       cb;
  151.     HWND        hList;
  152.  
  153.     if (NULL==m_pObj->m_hList || NULL==pFE || NULL==pSTM)
  154.         return ResultFromScode(DATA_E_FORMATETC);
  155.  
  156.     //We only support IStorage
  157.     if (!(TYMED_ISTORAGE & pFE->tymed))
  158.         return ResultFromScode(DATA_E_FORMATETC);
  159.  
  160.     hList=m_pObj->m_hList;
  161.     cItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L);
  162.  
  163.     for (i=0; i < cItems; i++)
  164.         {
  165.         cb=SendMessage(hList, LB_GETTEXT, i, (LPARAM)(LPVOID)&pRen);
  166.  
  167.         if (sizeof(LPRENDERING)==cb)
  168.             {
  169.             /*
  170.              * When we find a matching FORMATETC, we know we're only
  171.              * looking for IStorage (we checked above), so use
  172.              * IStorage::CopyTo to make the copy.
  173.              */
  174.             if (pFE->cfFormat==pRen->fe.cfFormat
  175.                 && (pFE->tymed & pRen->fe.tymed)
  176.                 && pFE->dwAspect==pRen->fe.dwAspect)
  177.                 {
  178.                 pSTM->tymed=TYMED_ISTORAGE;
  179.                 return pRen->stm.pstg->CopyTo(NULL, NULL, NULL, pSTM->pstg);
  180.                 }
  181.             }
  182.         }
  183.  
  184.     return ResultFromScode(DATA_E_FORMATETC);
  185.     }
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193. /*
  194.  * CImpIDataObject::QueryGetData
  195.  *
  196.  * Purpose:
  197.  *  Tests if a call to ::GetData with this FormatEtc will provide
  198.  *  any rendering; used like IsClipboardFormatAvailable.
  199.  *
  200.  * Parameters:
  201.  *  pFE             LPFORMATETC describing the desired data.
  202.  *
  203.  * Return Value:
  204.  *  HRESULT         NOERROR on success, error code otherwise.
  205.  */
  206.  
  207. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  208.     {
  209.     UINT        i, cItems;
  210.     LPRENDERING pRen;
  211.     DWORD       cb;
  212.     HWND        hList;
  213.  
  214.     if (NULL==m_pObj->m_hList || NULL==pFE)
  215.         return ResultFromScode(S_FALSE);
  216.  
  217.     hList=m_pObj->m_hList;
  218.     cItems=(UINT)SendMessage(hList, LB_GETCOUNT, 0, 0L);
  219.  
  220.     for (i=0; i < cItems; i++)
  221.         {
  222.         cb=SendMessage(hList, LB_GETTEXT, i, (LPARAM)(LPVOID)&pRen);
  223.  
  224.         if (sizeof(LPRENDERING)==cb)
  225.             {
  226.             /*
  227.              * Check if the requested FORMATETC is the same as one
  228.              * that we already have.
  229.              */
  230.             if (pFE->cfFormat==pRen->fe.cfFormat
  231.                 && (pFE->tymed & pRen->fe.tymed)
  232.                 && pFE->dwAspect==pRen->fe.dwAspect)
  233.                 {
  234.                 return NOERROR;
  235.                 }
  236.             }
  237.         }
  238.  
  239.     return ResultFromScode(S_FALSE);
  240.     }
  241.  
  242.  
  243.  
  244.  
  245. /*
  246.  * CImpIDataObject::SetData
  247.  *
  248.  * Purpose:
  249.  *  Places data described by a FormatEtc and living in a StgMedium
  250.  *  into the object.  The object may be responsible to clean up the
  251.  *  StgMedium before exiting.
  252.  *
  253.  * Parameters:
  254.  *  pFE             LPFORMATETC describing the data to set.
  255.  *  pSTM            LPSTGMEDIUM containing the data.
  256.  *  fRelease        BOOL indicating if this function is responsible for
  257.  *                  freeing the data.
  258.  *
  259.  * Return Value:
  260.  *  HRESULT         NOERROR on success, error code otherwise.
  261.  */
  262.  
  263. STDMETHODIMP CImpIDataObject::SetData(LPFORMATETC pFE, STGMEDIUM FAR *pSTM
  264.     , BOOL fRelease)
  265.     {
  266.     LPRENDERING     prn;
  267.  
  268.     //We have to remain responsible for the data.
  269.     if (!fRelease)
  270.         return ResultFromScode(E_FAIL);
  271.  
  272.     //If we're handed NULLs, that means clean out the list.
  273.     if (NULL==pFE || NULL==pSTM)
  274.         {
  275.         m_pObj->Purge();
  276.         return NOERROR;
  277.         }
  278.  
  279.     /*
  280.      * Here we take the rendering we're given and attach it to the
  281.      * end of the list.  We save the original pSTM->pUnkForRelease and
  282.      * replace it with our own such that each 'copy' of this data
  283.      * of actually just a reference count.
  284.      */
  285.  
  286.     prn=new RENDERING;
  287.  
  288.     if (NULL==prn)
  289.         return ResultFromScode(E_OUTOFMEMORY);
  290.  
  291.     prn->fe=*pFE;
  292.     prn->stm=*pSTM;
  293.     prn->pUnkOrg=pSTM->pUnkForRelease;
  294.     prn->stm.pUnkForRelease=(LPUNKNOWN)this;
  295.  
  296.     SendMessage(m_pObj->m_hList, LB_ADDSTRING, 0, (LONG)(LPVOID)prn);
  297.     return NOERROR;
  298.     }
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305. /*
  306.  * CImpIDataObject::EnumFormatEtc
  307.  *
  308.  * Purpose:
  309.  *  Returns an IEnumFORMATETC object through which the caller can iterate
  310.  *  to learn about all the data formats this object can provide through
  311.  *  either ::GetData[Here] or ::SetData.
  312.  *
  313.  * Parameters:
  314.  *  dwDir           DWORD describing a data direction, either DATADIR_SET
  315.  *                  or DATADIR_GET.
  316.  *  ppEnum          LPENUMFORMATETC FAR * in which to return the pointer
  317.  *                  to the enumerator.
  318.  *
  319.  * Return Value:
  320.  *  HRESULT         NOERROR on success, error code otherwise.
  321.  */
  322.  
  323. STDMETHODIMP CImpIDataObject::EnumFormatEtc(DWORD dwDir
  324.     , LPENUMFORMATETC FAR *ppEnum)
  325.     {
  326.     LPCEnumFormatEtc    pEnum;
  327.  
  328.     *ppEnum=NULL;
  329.  
  330.     /*
  331.      * From an external point of view there are no SET formats,
  332.      * because we want to allow the user of this component object
  333.      * to be able to stuff ANY format in via Set.  Only external
  334.      * users will call EnumFormatEtc and they can only Get.
  335.      */
  336.  
  337.     switch (dwDir)
  338.         {
  339.         case DATADIR_GET:
  340.              pEnum=new CEnumFormatEtc(m_punkOuter);
  341.              break;
  342.  
  343.         case DATADIR_SET:
  344.         default:
  345.             pEnum=NULL;
  346.             break;
  347.         }
  348.  
  349.     if (NULL==pEnum)
  350.         return ResultFromScode(E_FAIL);
  351.     else
  352.         {
  353.         //Let the enumerator copy our format list.
  354.         if (!pEnum->FInit(m_pObj->m_hList))
  355.             {
  356.             delete pEnum;
  357.             return ResultFromScode(E_FAIL);
  358.             }
  359.  
  360.         pEnum->AddRef();
  361.         }
  362.  
  363.     *ppEnum=pEnum;
  364.     return NOERROR;
  365.     }
  366.  
  367.  
  368.  
  369.  
  370.  
  371. /*
  372.  * CImpIDataObject::GetCanonicalFormatEtc
  373.  * CImpIDataObject::DAdvise
  374.  * CImpIDataObject::DUnadvise
  375.  * CImpIDataObject::EnumDAdvise
  376.  *
  377.  * Trivial member functions.
  378.  */
  379.  
  380. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc(LPFORMATETC pFEIn
  381.     , LPFORMATETC pFEOut)
  382.     {
  383.     return ResultFromScode(DATA_S_SAMEFORMATETC);
  384.     }
  385.  
  386. //No advise support for this sort of data transfer.
  387. STDMETHODIMP CImpIDataObject::DAdvise(LPFORMATETC pFE, DWORD dwFlags
  388.     , LPADVISESINK pIAdviseSink, LPDWORD pdwConn)
  389.     {
  390.     return ResultFromScode(E_FAIL);
  391.     }
  392.  
  393. STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
  394.     {
  395.     return ResultFromScode(E_FAIL);
  396.     }
  397.  
  398. STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA FAR *ppEnum)
  399.     {
  400.     return ResultFromScode(E_FAIL);
  401.     }
  402.